#pragma once

using namespace System;
using namespace System::Collections::Generic;
using namespace System::IO;
using namespace System::Resources;
using namespace System::Runtime::InteropServices;
using namespace System::Diagnostics;
using namespace System::Reflection;
using namespace System::Windows;
using namespace System::Windows::Media;
using namespace System::Windows::Media::Imaging;
using namespace CoreRay;

namespace CoreRay
{
	namespace DirectX
	{
		ref class DirectXRenderAccelerator : RenderAccelerator
		{
		private:
			
			int renderTargetsCount;
			ID3D10Device* graphicsDevice;
			ID3D10Effect* shader;
			ID3D10RenderTargetView** renderTargets;
			ID3D10DepthStencilView* depthStencil;
			ID3D10Texture2D** renderTargetTextures;
			ID3D10Texture2D** cpuOutputTextures;
			float** cpuOutputTextureData;
			Dictionary<String^, DirectXGeometryObject^>^ geometryObjectCache;
			
			void CreateDirect3DDevice();
			ID3D10Texture2D* CreateDirect3DTexture(int width, int height, bool isRenderTarget, bool isDepthStencil, bool isHardware);
			ID3D10Effect* CreateShader(String^ sourceCode);

		public:

			DirectXRenderAccelerator();
			~DirectXRenderAccelerator();
			!DirectXRenderAccelerator();

			virtual property String^ Name
			{
				String^ get() override sealed
				{
					return "Direct3D10";
				}
			}

			virtual void InitScene(Scene^ scene) override;
			virtual IEnumerable<Intersection^>^ FindPrimaryIntersections(Scene^ scene, RenderRegion^ renderRegion) override;
		};	
	}
}